package ch.bfh.fbi.hmac.android;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import android.util.Log;

public class HashMac{
	public enum HashMacType{
		HmacMD5("HmacMD5"),HmacSHA1("HmacSHA1");
		private String name;
		private HashMacType(String name){
			this.name=name;
		}
		public String getName() {
			return name;
		}
		public HashMacType getHashMacTypeByName(String name){
			if(name!=null&&name.contains("MD5")) return HmacMD5;
			if(name!=null&&name.contains("SHA1")) return HmacSHA1;
			return null;
		}
	}
	public static boolean isCorrectHashMac(HashMacType hashType, String key, String message,String hashMac)
	{
		String verification=createHashMac(hashType, key, message);
		return (verification!=null&&verification.equals(hashMac));
	}

    //String key = "d6fc3a4a06ed55d24fecde188aaa9161";
	// hashType="HmacMD5"
	public static String createHashMac(HashMacType hashType, String key, String message) {
		// http://stackoverflow.com/questions/3140650/how-to-generate-hmac-md5-in-android
		// http://token.sakura.ne.jp/wp/?cat=11
		String resultString = null;		
		try {
			if(hashType==null) throw new IllegalArgumentException("hashType missing");
			if(key==null)throw new IllegalArgumentException("key is missing");
			if(message==null)throw new IllegalArgumentException("message is missing");
			Mac mac = Mac.getInstance(hashType.getName());
			SecretKeySpec sk = new SecretKeySpec(key.getBytes(), hashType.getName());
			mac.init(sk);

			byte[] result = mac.doFinal(message.getBytes());

			resultString = byteToString(result);
			Log.i(hashType.getName(), resultString);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			Log.e("HashMac",e.getMessage());
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}
		return resultString;
	}

	private static String byteToString(byte[] b) {
		StringBuffer s = new StringBuffer();
		if(b==null) return s.toString();
		for (int i = 0; i < b.length; i++) {
			int d = b[i];
			d += d < 0 ? 256 : 0;
			// byte 128-255
			if (d < 16) {
				// 0-15 16
				s.append("0");
			}
			s.append(Integer.toString(d, 16));
		}
		return s.toString();
	}
}
